package me.zxk.smartagriculture.service;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.zxk.smartagriculture.entity.Greenhouse;
import me.zxk.smartagriculture.entity.GreenhouseSensorData;
import me.zxk.smartagriculture.repository.GreenhouseRepository;
import me.zxk.smartagriculture.repository.GreenhouseSensorDataRepository;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Random;

/**
 * 传感器数据服务
 * 用于模拟生成传感器数据
 */
@Service
@RequiredArgsConstructor
@Slf4j
@EnableAsync
public class SensorDataService {

    private final GreenhouseRepository greenhouseRepository;
    private final GreenhouseSensorDataRepository sensorDataRepository;
    private final Random random = new Random();

    /**
     * 定时生成传感器数据（每5分钟执行一次）
     */
    @Scheduled(fixedRate = 300000) // 5分钟
    @Async
    @Transactional
    public void generateSensorData() {
        try {
            List<Greenhouse> greenhouses = greenhouseRepository.findAll();
            for (Greenhouse greenhouse : greenhouses) {
                generateDataForGreenhouse(greenhouse);
            }
            log.debug("传感器数据生成完成，共处理{}个大棚", greenhouses.size());
        } catch (Exception e) {
            log.error("传感器数据生成失败: {}", e.getMessage());
        }
    }

    /**
     * 为指定大棚生成传感器数据
     */
    public void generateDataForGreenhouse(Greenhouse greenhouse) {
        // 生成模拟数据
        BigDecimal temperature = generateTemperature(greenhouse.getCurrentTemperature());
        BigDecimal humidity = generateHumidity(greenhouse.getCurrentHumidity());
        BigDecimal lightIntensity = generateLightIntensity(greenhouse.getCurrentLight());
        BigDecimal soilHumidity = generateSoilHumidity(greenhouse.getCurrentSoilHumidity());

        // 保存传感器数据
        GreenhouseSensorData sensorData = new GreenhouseSensorData();
        sensorData.setGreenhouseId(greenhouse.getId());
        sensorData.setTemperature(temperature);
        sensorData.setHumidity(humidity);
        sensorData.setLightIntensity(lightIntensity);
        sensorData.setSoilHumidity(soilHumidity);
        sensorData.setRecordedAt(LocalDateTime.now());

        sensorDataRepository.save(sensorData);

        // 更新大棚当前数据
        greenhouse.setCurrentTemperature(temperature);
        greenhouse.setCurrentHumidity(humidity);
        greenhouse.setCurrentLight(lightIntensity);
        greenhouse.setCurrentSoilHumidity(soilHumidity);
        greenhouseRepository.save(greenhouse);

        log.debug("为大棚{}生成传感器数据: 温度={}, 湿度={}, 光照={}, 土壤湿度={}", 
                greenhouse.getName(), temperature, humidity, lightIntensity, soilHumidity);
    }

    /**
     * 生成温度数据（在当前值基础上小幅波动）
     */
    private BigDecimal generateTemperature(BigDecimal currentTemp) {
        if (currentTemp == null) {
            currentTemp = new BigDecimal("25.0");
        }
        
        // 在当前温度基础上±2度范围内波动
        double variation = (random.nextDouble() - 0.5) * 4.0;
        double newTemp = currentTemp.doubleValue() + variation;
        
        // 限制在合理范围内（15-35度）
        newTemp = Math.max(15.0, Math.min(35.0, newTemp));
        
        return BigDecimal.valueOf(newTemp).setScale(1, RoundingMode.HALF_UP);
    }

    /**
     * 生成湿度数据
     */
    private BigDecimal generateHumidity(BigDecimal currentHumidity) {
        if (currentHumidity == null) {
            currentHumidity = new BigDecimal("60.0");
        }
        
        // 在当前湿度基础上±5%范围内波动
        double variation = (random.nextDouble() - 0.5) * 10.0;
        double newHumidity = currentHumidity.doubleValue() + variation;
        
        // 限制在合理范围内（30-90%）
        newHumidity = Math.max(30.0, Math.min(90.0, newHumidity));
        
        return BigDecimal.valueOf(newHumidity).setScale(1, RoundingMode.HALF_UP);
    }

    /**
     * 生成光照强度数据
     */
    private BigDecimal generateLightIntensity(BigDecimal currentLight) {
        if (currentLight == null) {
            currentLight = new BigDecimal("3000.0");
        }
        
        // 根据时间调整光照强度（简单模拟白天夜晚）
        int hour = LocalDateTime.now().getHour();
        double baseIntensity;
        
        if (hour >= 6 && hour <= 18) {
            // 白天：较高光照
            baseIntensity = 3000.0 + (random.nextDouble() - 0.5) * 1000.0;
        } else {
            // 夜晚：较低光照
            baseIntensity = 500.0 + (random.nextDouble() - 0.5) * 200.0;
        }
        
        // 限制在合理范围内（0-5000 lux）
        baseIntensity = Math.max(0.0, Math.min(5000.0, baseIntensity));
        
        return BigDecimal.valueOf(baseIntensity).setScale(1, RoundingMode.HALF_UP);
    }

    /**
     * 生成土壤湿度数据
     */
    private BigDecimal generateSoilHumidity(BigDecimal currentSoilHumidity) {
        if (currentSoilHumidity == null) {
            currentSoilHumidity = new BigDecimal("50.0");
        }
        
        // 在当前土壤湿度基础上±3%范围内波动
        double variation = (random.nextDouble() - 0.5) * 6.0;
        double newSoilHumidity = currentSoilHumidity.doubleValue() + variation;
        
        // 限制在合理范围内（20-80%）
        newSoilHumidity = Math.max(20.0, Math.min(80.0, newSoilHumidity));
        
        return BigDecimal.valueOf(newSoilHumidity).setScale(1, RoundingMode.HALF_UP);
    }
}
